#include "Camera.h"
#include <iostream>
#include <chrono>

using namespace std;
using namespace cv;

UsbCamera::UsbCamera(const string& device, int width, int height, int fps)
    : device_(device), width_(width), height_(height), fps_(fps), running_(false) {}

UsbCamera::~UsbCamera() {
    stop();
}

bool UsbCamera::start() {
    //尝试释放可能被占用的摄像头
    std::string cmd = "fuser -k "+device_ ;
    system(cmd.c_str());  // 忽略返回值，即使关闭失败也继续


    std::cout << "[Camera] 尝试启动摄像头：设备=" << device_ << "，分辨率=" << width_ << "x" << height_ << "，帧率=" << fps_ << std::endl;

    // 改用 CAP_V4L2 后端，直接打开设备节点（不依赖 GStreamer）
    cap_.open(device_, CAP_V4L2);
    if (!cap_.isOpened()) {
        std::cerr << "[Camera] 无法打开设备节点：" << device_ << std::endl;
        return false;
    }

    std::cout << "[Camera] 设置参数：分辨率=" << width_ << "x" << height_ 
                << "，帧率=" << fps_ << std::endl;
                
    // 2. 强制设置格式为 MJPEG（必须在设置分辨率前）
    bool format_ok = cap_.set(CAP_PROP_FOURCC, VideoWriter::fourcc('M', 'J', 'P', 'G'));
    // 3. 强制设置分辨率（640x480）
    bool width_ok = cap_.set(CAP_PROP_FRAME_WIDTH, width_);
    bool height_ok = cap_.set(CAP_PROP_FRAME_HEIGHT, height_);
    cap_.set(CAP_PROP_FPS, fps_); // 设置帧率

    // 验证设置是否生效（关键：确认实际参数与配置一致）
    int actual_width = cap_.get(CAP_PROP_FRAME_WIDTH);
    int actual_height = cap_.get(CAP_PROP_FRAME_HEIGHT);
    int actual_fps = cap_.get(CAP_PROP_FPS);
    int actual_fourcc = cap_.get(CAP_PROP_FOURCC);
    std::cout << "[Camera] 实际参数：分辨率=" << actual_width << "x" << actual_height 
              << "，帧率=" << actual_fps 
              << "，格式=" << (char)(actual_fourcc&0xFF) << (char)((actual_fourcc>>8)&0xFF) 
              << (char)((actual_fourcc>>16)&0xFF) << (char)((actual_fourcc>>24)&0xFF) << std::endl;

    // 若实际参数与配置不一致，说明摄像头不支持该配置，直接返回失败
    if (actual_width != width_ || actual_height != height_) {
        std::cerr << "[Camera] 摄像头不支持该分辨率，建议改用：" << actual_width << "x" << actual_height << std::endl;
        cap_.release();
        return false;
    }

    running_ = true;
    capture_thread_ = thread(&UsbCamera::captureLoop, this);
    std::cout << "[Camera] 摄像头启动成功（V4L2 后端）" << std::endl;
    return true;
}

void UsbCamera::stop() {
    if (running_) {
        running_ = false;
        if (capture_thread_.joinable()) {
            capture_thread_.join();
        }
        cap_.release();
        cout << "[Camera] 摄像头已停止" << endl;
    }
}

bool UsbCamera::getFrame(vector<uchar>& mjpeg_frame) {
    if (!running_) return false;

    lock_guard<mutex> lock(frame_mutex_);
    if (frame_.empty()) {
        // 仅调试时输出，正常运行时注释
        // cerr << "[Camera] 帧缓存为空" << endl;
        return false;
    }

    mjpeg_frame.clear();
    if (!imencode(".jpg", frame_, mjpeg_frame, vector<int>{IMWRITE_JPEG_QUALITY, 60})) {
        cerr << "[Camera] MJPEG 编码失败" << endl;
        return false;
    }

    // 仅保留关键日志（帧过小才报警）
    if (mjpeg_frame.size() < 1024) {
        cerr << "[Camera] 编码后帧过小（" << mjpeg_frame.size() << "字节），可能是无效画面" << endl;
    } else {
        static int cnt = 0;
        if (++cnt % 50 == 0) {  // 每 50 帧打印一次，减少日志频率
            cout << "[Camera] 有效帧大小：" << mjpeg_frame.size() << "字节" << endl;
        }
    }

    return true;
}

bool UsbCamera::isRunning() const {
    return running_;
}

void UsbCamera::captureLoop() {
    while (running_) {
        Mat temp_frame;
        // 兼容旧版 OpenCV 的读取方式（无超时参数，直接读取）
        bool read_success = cap_.read(temp_frame);

        // 加锁更新帧缓存（避免与 getFrame 竞争）
        if (read_success && !temp_frame.empty())
        {
            // 🔴 新增：垂直翻转（解决上下颠倒，开销可忽略）
            cv::flip(temp_frame, temp_frame, 0);  // 参数 0 = 垂直镜像

            lock_guard<mutex> lock(frame_mutex_);
            frame_ = temp_frame;  // 直接赋值，无需 clone()，提升效率
        }

        // 仅保留 1ms 延迟，平衡性能和帧更新速度
        this_thread::sleep_for(chrono::milliseconds(20));
    }
}